package com.jeesite.modules.dataScreen.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jeesite.modules.dataScreen.constants.BgManageExceptions;
import com.jeesite.modules.dataScreen.constants.SysUserStateConstants;
import com.jeesite.modules.dataScreen.dao.SysUserDao;
import com.jeesite.modules.dataScreen.entity.SysUser;
import com.jeesite.modules.dataScreen.service.SysRoleService;
import com.jeesite.modules.dataScreen.service.SysUserService;
import com.jeesite.modules.dataScreen.web.dto.LoginDto;
import com.jeesite.modules.dataScreen.web.dto.SysUserDto;
import com.jeesite.modules.dataScreen.web.dto.SysUserPageSearchDto;
import com.jeesite.modules.dataScreen.web.vo.LoginVo;
import com.jeesite.modules.dataScreen.web.vo.SysUserPageVo;
import com.jeesite.modules.dataScreen.web.vo.SysUserVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 系统用户(SysUser)表服务实现类
 *
 * @author makejava
 * @since 2024-09-24 15:29:56
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserDao, SysUser> implements SysUserService {

    @Resource
    private SysRoleService roleService;

    @Override
    public LoginVo login(LoginDto dto) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getUserName, dto.getUsername());
        SysUser sysUser = getBaseMapper().selectOne(wrapper);
        if (sysUser == null) {
            throw BgManageExceptions.AUTH_FAILED;
        }
        if (!Objects.equals(sysUser.getState(), SysUserStateConstants.NORMAL)) {
            throw BgManageExceptions.ABNORMAL;
        }
        String sha256 = SaSecureUtil.sha256(dto.getPassword());
        if (!sha256.equals(sysUser.getPassword())) {
            throw BgManageExceptions.AUTH_FAILED;
        }
        //登录
        StpUtil.login(sysUser.getId());
        LoginVo loginVo = new LoginVo();
        loginVo.setTokenName(StpUtil.getTokenName());
        loginVo.setTokenVal(StpUtil.getTokenValue());
        loginVo.setUsername(sysUser.getUserName());
        //获取首页地址
        roleService.loginAfterRole(sysUser.getId(), loginVo);
        //更新登录时间
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysUser::getLastLoginTime, new Date());
        update(updateWrapper);
        return loginVo;
    }

    @Override
    public String resetPassword(JSONObject dto) {
        Integer userId = dto.getInteger("userId");
        String pass = dto.getString("password");
        checkAdmin(userId);
//        String pass = IdUtil.nanoId(8);
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysUser::getPassword, SaSecureUtil.sha256(pass));
        updateWrapper.eq(SysUser::getId, userId);
        update(updateWrapper);
        StpUtil.logout(userId);
        return pass;
    }


    @Override
    public void freeze(Integer userId) {
        checkAdmin(userId);
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysUser::getState, 2);
        updateWrapper.eq(SysUser::getId, userId);
        updateWrapper.eq(SysUser::getState, 1);
        update(updateWrapper);
    }

    public void undoFreeze(Integer userId) {
        checkAdmin(userId);
        LambdaUpdateWrapper<SysUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysUser::getState, 1);
        updateWrapper.eq(SysUser::getId, userId);
        updateWrapper.eq(SysUser::getState, 2);
        update(updateWrapper);
    }

    @Override
    public List<SysUserPageVo> list(SysUserPageSearchDto dto) {
        return getBaseMapper().customList(dto);
    }

    @Override
    public SysUserVo detail(Integer userId) {
        return getBaseMapper().detail(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysUserDto dto) {
        Integer id = dto.getId();
        //管理员不可编辑
        checkAdmin(id);
        SysUser sysUser = new SysUser();
        sysUser.setId(id);
        String userName = dto.getName().trim();
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysUser::getUserName, userName);
        SysUser user = getOne(queryWrapper);
        if (Objects.nonNull(user) && !Objects.equals(user.getId(), id)) {
            throw BgManageExceptions.USER_EXISTS;
        }
        sysUser.setUserName(userName);
        if (id == null) {
            sysUser.setState(SysUserStateConstants.NORMAL);
            sysUser.setCreateAt(DateUtil.date());
        }
        if (StrUtil.isNotBlank(dto.getPassword())) {
            sysUser.setPassword(SaSecureUtil.sha256(dto.getPassword()));
        }
        sysUser.setUpdateAt(DateUtil.date());
        sysUser.setRemark(dto.getRemark());
        saveOrUpdate(sysUser);

        //更新角色
        roleService.updateByUserId(sysUser.getId(), dto.getRoleId());
    }

    @Override
    public void delete(Integer userId) {
        checkAdmin(userId);
        removeById(userId);
    }

    private void checkAdmin(Integer userId) {
        if (userId == null) {
            return;
        }
        if (userId == 1) {
            throw BgManageExceptions.ACCESS_DENIED;
        }
    }

}

